﻿using System;
using System.Collections.Generic;
using System.Data.Linq;
using System.Linq;
using Quickie.Models;
using Quickie.Models.IoC;
using Quickie.Models.Data;
using Quickie.Models.Entities;
using Quickie.Models.ViewModel;
using Quickie.Models.Interfaces;

namespace Quickie.Models.Data
{
    /// <summary>
    /// Klasa koja predstavlja vezu između stvarnog objekta
    /// Product i tablice Product u bazi podataka
    /// </summary>
    public class ProductRepository : IRepository<Product>
    {
        private readonly IDataProvider data;

        /// <summary>
        /// Konstruktor klase Product
        /// </summary>
        /// <param name="data">Predstavlja data izvor</param>
        public ProductRepository(IDataProvider data)
        {
            this.data = data;
        }

        /// <summary>
        /// Metoda koja vraća sve proizvode u bazi podataka
        /// </summary>
        /// <returns></returns>
        public IQueryable<Product> GetAll()
        {
            return data.Linq<Product>();
        }

        /// <summary>
        /// Metoda koja vraća određene proizvode iz baze podataka,
        /// određene prema jedinstvenom ID-u.
        /// </summary>
        /// <param name="ID">Jedinstveni parametar proizvoda</param>
        /// <returns></returns>
        public Product GetByID(int ID)
        {
            try
            {
                return GetAll().Single(x => x.ID == ID);
            }
            catch (Exception)
            {
                return null;
            }
        }

        /// <summary>
        /// Metoda koja sprema novi/postojeci proizvod
        /// u bazu podataka.
        /// </summary>
        /// <param name="product">Proizvod koji zelimo sacuvati</param>
        public void Save(Product item)
        {
            data.Insert(item);
            data.SubmitChanges();
        }

        /// <summary>
        /// Metoda koja brise odredeni proizvod.
        /// </summary>
        /// <param name="product">Proizvod koji zelimo izbrisati</param>
        public void Delete(Product item)
        {
            data.Delete(item);
        }

        /// <summary>
        /// Metoda koja sprema sve napravljene promjene
        /// i izmjene u bazu podataka.
        /// </summary>
        public void SaveChanges()
        {
            data.SubmitChanges();
        }
    }

    /// <summary>
    /// Pomocna klasa za odredivanje veze izmedu kategorije
    /// i proizvoda.
    /// </summary>
    public static class ProductRepExtensions
    {
        /// <summary>
        /// Metoda koja vraca listu proizvoda iz odredene kategorije
        /// </summary>
        /// <param name="source">Izvor podataka</param>
        /// <param name="ID">ID kategorije</param>
        /// <returns></returns>
        public static List<Product> FromCategory(this IRepository<Product> source, int ID)
        {
            var context = new DataClassesDataContext();
            var options = new DataLoadOptions();
            options.LoadWith<Product>(p => p.Category);
            context.LoadOptions = options;

            var prods = from c in context.Categories
                        join p in context.Products on c.ID equals p.CategoryID
                        where c.ID == ID || c.ParentID == ID
                        select p;

            return prods.ToList();
        }
    }

}
